package com.barradata.app0624.modules.contact

import android.Manifest
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.provider.ContactsContract
import androidx.recyclerview.widget.LinearLayoutManager
import com.barradata.BuildConfig
import com.barradata.R
import com.barradata.app0624.api.ApiService
import com.barradata.app0624.modules.web.EventType
import com.barradata.app0624.modules.web.WebCallbackEvent
import com.barradata.common.base.BaseActivity
import com.barradata.common.rxbus.RxBus
import com.barradata.common.utils.ToastUtils
import com.barradata.common.view.AlertDialogFragment
import com.barradata.common.view.PlainTextPopupFragment
import com.example.hfiveandaplication.bean.ContactItemInfoData
import com.example.hfiveandaplication.bean.DictionaryItemData
import com.tbruyelle.rxpermissions2.RxPermissions
import io.reactivex.functions.Consumer
import kotlinx.android.synthetic.main.contact_activity.toolbar
import kotlinx.android.synthetic.main.contact_activity2.*

/**
 * Author:    WuNan
 * Email:     geek5nan@gmail.com
 * Created:   2019-07-14 12:02
 **/
class ContactActivity2 : BaseActivity() {
    companion object {
        fun actionStart(context: Context) {
            context.startActivity(Intent(context, ContactActivity2::class.java))
        }

        private const val REQUEST_PERMISSION = Manifest.permission.READ_CONTACTS

        private const val CONTACT_SIZE = 3
    }

    private val rxPermissions = RxPermissions(this)

    private var relationDicList = mutableListOf<DictionaryItemData>()

    private var contactItemList = mutableListOf<ContactItemInfoData>()


    override fun getLayoutId() = R.layout.contact_activity2

    override fun initView() {
        setupActionBar(toolbar)
        requestPermission()
        fetchDicData()
        setupRecyclerView()
    }

    override fun onBackPressed() {
        super.onBackPressed()
        RxBus.post(WebCallbackEvent(EventType.FROM_CANCEL))
    }

    private fun setupRecyclerView() {
        for (i in 0 until CONTACT_SIZE) {
            contactItemList.add(ContactItemInfoData().apply {
                orderNo = (i + 1).toString()
            })
        }
        recycler_view.layoutManager = LinearLayoutManager(this)
        recycler_view.adapter = ContactAdapter(this, contactItemList,
                this::phoneButtonAction, this::relationButtonAction, this::nextButtonAction)
    }

    private fun phoneButtonAction(position: Int) {
        actionStartContactPicker(requestCode = position)
    }

    private fun relationButtonAction(position: Int) {
        showDicFragment(position)
    }

    private fun nextButtonAction() {
        if (!validateFormData()) {
            return
        }
        ApiService.uploadContactInfo(contactItemList).doOnSubscribe { showLoadingView() }.doFinally { dismissLoadingView() }
                .subscribe({
                    if (it.status == 200) {
                        RxBus.post(WebCallbackEvent(EventType.FROM_CONTACT))
                        finish()
                    } else {
                        ToastUtils.showShort(it.message)
                    }
                }, {
                    ToastUtils.showShort(R.string.network_error)
                }).autoClean()
    }

    private fun validateFormData(): Boolean {
        contactItemList.forEachIndexed { index, contactItem ->
            contactItem.apply {
                if (userName.isNullOrBlank()) {
                    val toastStr = String.format(getString(R.string.contact_auth_phone_hint_format), index + 1)
                    ToastUtils.showShort(toastStr)
                    return false
                } else if (relation.isNullOrBlank() || realtionValue.isNullOrBlank()) {
                    val toastStr = String.format(getString(R.string.contact_auth_relation_hint_format), index + 1)
                    ToastUtils.showShort(toastStr)
                    return false
                } else if (mobile.isNullOrBlank()) {
                    val toastStr = String.format(getString(R.string.contact_auth_phone_hint_format), index + 1)
                    ToastUtils.showShort(toastStr)
                    return false
                }
            }
        }
        return true
    }


    private fun fetchDicData() {
        ApiService.getDictionary(ApiService.DictionaryType.COMMON_RELATION)
                .doOnSubscribe { showLoadingView() }
                .doFinally { dismissLoadingView() }
                .subscribe({
                    if (it.isRel && it.data != null) {
                        relationDicList.clear()
                        relationDicList.addAll(it.data)
                    }
                }, {
                    ToastUtils.showShort(R.string.network_error)
                }).autoClean()
    }

    private fun showDicFragment(position: Int) {
        if (relationDicList.size == 0) {
            fetchDicData()
            return
        }
        PlainTextPopupFragment(relationDicList.map { it.dictValue }).also {
            it.callbackAction = { selectedIndex ->
                val selectedRelation = relationDicList[selectedIndex]
                contactItemList[position].relation = selectedRelation.dictCode
                contactItemList[position].realtionValue = selectedRelation.dictValue
                recycler_view.adapter?.notifyItemChanged(position)
            }
        }.show(this)
    }


    private fun checkPermission(): Boolean {
        if (rxPermissions.isGranted(REQUEST_PERMISSION)) {
            return true
        } else {
            requestPermission()
            return false
        }
    }

    private fun requestPermission() {
        rxPermissions.requestEach(REQUEST_PERMISSION).subscribe {
            if (it.granted) {
                return@subscribe
            }
            val singleButtonAction: ()->Unit
            if (it.shouldShowRequestPermissionRationale) {
                singleButtonAction =  { requestPermission() }
            } else {
                singleButtonAction =  { actionStartAppSetting() }
            }
            ToastUtils.showShort(R.string.get_permission_failure_hint)
            AlertDialogFragment.create(singleButtonAction).setCancelAble(false)
                    .setTitle(getString(R.string.get_permission_failure_hint))
                    .show(this)
        }.autoClean()
    }

    private fun actionStartAppSetting() {
        val localIntent = Intent()
        localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        localIntent.action = "android.settings.APPLICATION_DETAILS_SETTINGS"
        localIntent.data = Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)
        startActivity(localIntent)
    }

    private fun actionStartContactPicker(requestCode: Int) {
        if (!checkPermission()) {
            return
        }
        val intent = Intent(Intent.ACTION_PICK)
        intent.setDataAndType(ContactsContract.CommonDataKinds.Phone.CONTENT_URI
                , ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE)
        startActivityForResult(intent, requestCode)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (data == null || data.data == null) {
            return
        }
        val contactInfo = resolveContactCursor(data.data)
        val contactName = contactInfo[0]
        val contactPhoneNumber = contactInfo[1]
        if (isMobileRepeat(contactPhoneNumber, currentIndex = requestCode)) {
            ToastUtils.showShort(R.string.contact_auth_contact_repeat)
            return
        }
        contactItemList[requestCode].mobile = contactPhoneNumber
        contactItemList[requestCode].userName = contactName
        recycler_view.adapter?.notifyItemChanged(requestCode)
    }

    private fun resolveContactCursor(data: Uri?): Array<String?> {
        val cursor = contentResolver.query(data,
                arrayOf(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
                        , ContactsContract.CommonDataKinds.Phone.NUMBER),
                null, null, null)
        cursor?.moveToFirst()
        val contactName = cursor?.getString(0)
        val phoneNumber = cursor?.getString(1)
        logD(contactName.orEmpty() + phoneNumber.orEmpty())
        cursor?.close()
        return arrayOf(contactName, phoneNumber)
    }

    private fun isMobileRepeat(mobile: String?, currentIndex: Int): Boolean {
        return contactItemList.filterIndexed { index, _ ->
            if (index == currentIndex) {
                return@filterIndexed false
            }
            return@filterIndexed true
        }.map { it.mobile }.contains(mobile)
    }
}